package org.hang.gift.service.impl;


import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import org.hang.gift.domain.TenantType;
import org.hang.gift.mapper.TenantTypeMapper;
import org.hang.gift.service.ITenantTypeService;
import org.redisson.api.RLock;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.redisson.api.RedissonClient;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author hang
 * @since 2024-05-30
 */
@Service
public class TenantTypeServiceImpl extends ServiceImpl<TenantTypeMapper, TenantType> implements ITenantTypeService {

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private RedissonClient redissonClient;

    private final String TENANT_TYPE_IN_REDIS = "tenant_type_in_redis";


    @Override
    public List<TenantType> selectList(Wrapper<TenantType> wrapper) {
        // 1 从缓存中获取数据
        Object obj = redisTemplate.opsForValue().get(TENANT_TYPE_IN_REDIS);

        // 2 如果存在,则直接返回
        if(Objects.nonNull(obj)){
            return (List<TenantType>)obj;
        }

        // 3 如果不存在
        // 1w请求过来以后  1 . 2第一个请求抢到锁以后,缓存中其实就已经有数据,后续的请求就没有必要再去查询数据库
        RLock lock = redissonClient.getLock(TENANT_TYPE_IN_REDIS);
        try {
            lock.lock();
            obj = redisTemplate.opsForValue().get(TENANT_TYPE_IN_REDIS);

            // 2 如果存在,则直接返回
            if(Objects.nonNull(obj)){
                return (List<TenantType>)obj;
            }
            // 3.1 从数据库中查询数据
            List<TenantType> tenantTypes = super.selectList(wrapper);
            if(tenantTypes == null){
                // 如果为空,给一个默认值,解决缓存穿透问题
                tenantTypes = new ArrayList<>();
            }
            // 3.2 将查询出的数据放入缓存
            redisTemplate.opsForValue().set(TENANT_TYPE_IN_REDIS,tenantTypes);
            // 3.3 将数据返回给前端
            return tenantTypes;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }finally {
            lock.unlock();
        }
    }


    @Override
    public boolean insert(TenantType entity) {
        // 操作数据库
        boolean flag = super.insert(entity);

        // 删除缓存
        redisTemplate.delete(TENANT_TYPE_IN_REDIS);

        return flag;
    }

    @Override
    public boolean updateById(TenantType entity) {
        boolean flag = super.updateById(entity);
        // 删除缓存
        redisTemplate.delete(TENANT_TYPE_IN_REDIS);

        return flag;
    }

    @Override
    public boolean deleteById(Serializable id) {
        boolean flag =  super.deleteById(id);
        // 删除缓存
        redisTemplate.delete(TENANT_TYPE_IN_REDIS);

        return flag;
    }
}
